package com.example.demo.untils;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;


public class FileUtil {
    private static final int BUFFER_SIZE = 4096;

    /*public static String getMD5Hex(File file) {
        try (InputStream is = new FileInputStream(file)){
            byte[] md5 = EncryptUtil.getMessageDigest(EncryptUtil.Type.MD5, is);
            return StringUtil.bytesToHex(md5);
        } catch (Exception e) {
            System.err.println(e.toString());
        }

        return null;
    }*/

    public static File fileDownload(String url, String savePath) {
        return fileDownload(url, savePath, false);
    }

    public static File fileDownload(String url, String savePath, boolean autoUnzip) {
        try {
            StringBuilder filePath = new StringBuilder(savePath);
            if (!savePath.endsWith(File.separator)) {
                filePath.append(File.separator);
            }

            String fileName = url.substring(url.lastIndexOf("/") + 1);
            int pos = fileName.indexOf("?");
            if (pos >= 0) {
                fileName = fileName.substring(0, pos);
            }

            if (StringUtils.isEmpty(fileName)) {
                fileName = DigestUtils.md5DigestAsHex(url.getBytes());
            }

            File tempFile = new File(filePath.toString() + fileName + ".tmp");
            FileUtils.copyURLToFile(new URL(url), tempFile);
            File destFile = new File(filePath.toString() + fileName);

            if (autoUnzip && EncryptUtil.isGzip(tempFile)) {
                try (InputStream fileInputStream = new FileInputStream(tempFile);
                     InputStream inputStream = new GZIPInputStream(fileInputStream);
                     OutputStream outputStream = new FileOutputStream(destFile)) {

                    copyStream(inputStream, outputStream);
                } catch (Exception e) {
                    System.err.println(e.toString());
                    return null;
                }

                tempFile.delete();
            } else {
                if (destFile.exists() && !destFile.isDirectory()) {
                    destFile.delete();
                }

                tempFile.renameTo(destFile);
            }

            return destFile;
        } catch (Exception e) {
            System.err.println(e.toString());
        }

        return null;
    }

    public static List<String> fileUpload(HttpServletRequest req, String savePath) {
        try {
            File file = new File(savePath);
            if (!file.exists() || !file.isDirectory()) {
                file.mkdir();
            }

            if (!savePath.endsWith(File.separator)) {
                savePath += File.separator;
            }

            if (!ServletFileUpload.isMultipartContent(req)) {
                return null;
            }

            ServletFileUpload fileUpload = new ServletFileUpload(new DiskFileItemFactory());
            fileUpload.setHeaderEncoding("utf-8");

            List<FileItem> fileItems = fileUpload.parseRequest(req);
            if (fileItems == null || fileItems.isEmpty()) {
                return null;
            }

            List<String> uploadFileList = new LinkedList<>();

            for (FileItem fileItem : fileItems) {
                if (!fileItem.isFormField()) {
                    String fileName = fileItem.getName();
                    if (!StringUtils.isEmpty(fileName)) {
                        fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);

                        try (InputStream inputStream = fileItem.getInputStream();
                             OutputStream outputStream = new FileOutputStream(savePath + fileName)) {
                            copyStream(inputStream, outputStream);
                        }

                        uploadFileList.add(savePath + fileName);
                    }
                }
            }

            return uploadFileList;
        } catch (Exception e) {
            System.err.println(e.toString());
        }

        return null;
    }

    public static void copyStream(InputStream is, OutputStream os) throws IOException {
        int len = 0;
        byte buffer[] = new byte[BUFFER_SIZE];
        while ((len = is.read(buffer)) > 0) {
            os.write(buffer, 0, len);
        }
        os.flush();
    }
}
